package com.liming.user.service.impl;

import com.liming.auth.client.UserAuthClient;
import com.liming.common.constant.SystemConstants;
import com.liming.common.enums.OperationTypeEnum;
import com.liming.common.pojo.dto.PageDTO;
import com.liming.common.pojo.dto.authinfo.UserActivityAddDTO;
import com.liming.common.pojo.dto.product.MiniProductPageQuery;
import com.liming.common.pojo.vo.PageVO;
import com.liming.common.pojo.vo.coupon.mini.MiniCouponVO;
import com.liming.common.pojo.vo.coupon.openfeign.FeignMiniCouponVO;
import com.liming.common.pojo.vo.product.CategoryVO;
import com.liming.common.pojo.vo.product.MiniProductDetailVO;
import com.liming.common.pojo.vo.product.MiniProductVO;
import com.liming.common.pojo.vo.product.openfeign.FeignMiniProductDetailVO;
import com.liming.common.pojo.vo.product.openfeign.FeignMiniProductVO;
import com.liming.common.util.BeanUtils;
import com.liming.common.util.PageUtils;
import com.liming.common.util.ThreadLocalUtils;
import com.liming.coupon.client.CouponUserClient;
import com.liming.product.client.CategoryClient;
import com.liming.product.client.ProductClient;
import com.liming.user.service.ProductService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * @author liming
 * @date 2025/3/22
 */
@Service
@AllArgsConstructor
public class ProductServiceImpl implements ProductService {

    private final ProductClient productClient;
    private final CouponUserClient couponUserClient;
    private final CategoryClient categoryClient;
    private final UserAuthClient userAuthClient;

    @Override
    public List<MiniProductVO> recommend() {
        List<FeignMiniProductVO> feignResult = productClient.recommendProduct();
        return BeanUtils.toBean(feignResult, MiniProductVO.class);
    }

    @Override
    public MiniProductDetailVO detail(Long id) {
        FeignMiniProductDetailVO feignResult = productClient.miniDetail(id);
        Map<Long, Integer> productIdAndPriceMap = new HashMap<>();
        productIdAndPriceMap.put(id, feignResult.getPrice());
        Map<Long, List<FeignMiniCouponVO>> couponMap = couponUserClient.productCanUseCoupons(productIdAndPriceMap);
        MiniProductDetailVO result = BeanUtils.toBean(feignResult, MiniProductDetailVO.class);
        List<FeignMiniCouponVO> feignMiniCouponVOList = couponMap.getOrDefault(id, List.of());
        List<MiniCouponVO> miniCouponVOList = BeanUtils.toBean(feignMiniCouponVOList, MiniCouponVO.class);
        result.setCoupons(miniCouponVOList);

        CompletableFuture.runAsync(() -> {
            UserActivityAddDTO userActivityAddDTO = new UserActivityAddDTO();
            userActivityAddDTO.setOperationType(OperationTypeEnum.BROWSE.getCode());
            userActivityAddDTO.setUserId(Long.parseLong(ThreadLocalUtils.get(SystemConstants.ID)));
            userActivityAddDTO.setKeyId(id);
            userAuthClient.addUserActivity(userActivityAddDTO);
        });
        return result;
    }

    @Override
    public PageVO<MiniProductVO> page(MiniProductPageQuery query) {
        PageVO<FeignMiniProductVO> feignResult = productClient.miniPage(query);
        // 获取所有商品的id、价格
        Map<Long, Integer> productIdAndPriceMap = feignResult.getRecords().stream().collect(Collectors.toMap(FeignMiniProductVO::getId, FeignMiniProductVO::getPrice));
        // 获取所有商品能够使用的最好的优惠券
        Map<Long, List<FeignMiniCouponVO>> couponMap = couponUserClient.productCanUseCoupons(productIdAndPriceMap);
        List<FeignMiniProductVO> records = feignResult.getRecords();
        for (FeignMiniProductVO record : records) {
            record.setCoupons(couponMap.getOrDefault(record.getId(), List.of()));
        }
        PageVO<MiniProductVO> result = new PageVO<>();
        PageUtils.copyPropertiesAndField(feignResult, result, MiniProductVO.class, "coupons", MiniCouponVO.class);

        CompletableFuture.runAsync(() -> {
            UserActivityAddDTO userActivityAddDTO = new UserActivityAddDTO();
            userActivityAddDTO.setOperationType(OperationTypeEnum.SEARCH.getCode());
            userActivityAddDTO.setUserId(Long.parseLong(ThreadLocalUtils.get(SystemConstants.ID)));
            userAuthClient.addUserActivity(userActivityAddDTO);
        });
        return result;
    }

    @Override
    public PageVO<CategoryVO> pageCategoryQuery(PageDTO page) {
        return categoryClient.page(page);
    }
}
